package org.soenea.doitall.application;

import java.io.IOException;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dsrg.soenea.service.MySQLConnectionFactory;
import org.dsrg.soenea.service.registry.Registry;
import org.dsrg.soenea.service.threadLocal.DbRegistry;
import org.dsrg.soenea.service.threadLocal.ThreadLocalTracker;
import org.soenea.doitall.application.dispatcher.BuddyAgeDispatcher;

public class FrontController extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Override
	public void init() throws ServletException {
		super.init();
		prepareDbRegistry("");
	}

	public static void prepareDbRegistry(String db_id) {
		MySQLConnectionFactory f = new MySQLConnectionFactory(null, null, null,
				null);
		try {
			f.defaultInitialization(db_id);
		} catch (SQLException e2) {
			e2.printStackTrace();
		}
		DbRegistry.setConFactory(db_id, f);
		String tablePrefix;
		try {
			tablePrefix = Registry.getProperty(db_id + "mySqlTablePrefix");
		} catch (Exception e1) {
			e1.printStackTrace();
			tablePrefix = "";
		}
		if (tablePrefix == null) {
			tablePrefix = "";
		}
		DbRegistry.setTablePrefix(db_id, tablePrefix);
	}

	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		BuddyAgeDispatcher fc = getFrontCommand(request);
		if (fc == null) {
			String msg = "Invalid or unspecified command";
			String command = getParameterOrAttribute(request, "command");
			if (command != null)
				msg += " (" + command + ")";
			response.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
		} else {
			fc.init(request, response);
			fc.execute();
		}
	}

	private BuddyAgeDispatcher getFrontCommand(HttpServletRequest request) {
		try {
			String command = getParameterOrAttribute(request, "command");
			if (command == null || command.isEmpty()) {
				return null;
			}
			String fqCommand = "org.soenea.doitall.application.dispatcher."
					+ command;
			return (BuddyAgeDispatcher) Class.forName(fqCommand).newInstance();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		preProcessRequest(request, response);
		try {
			processRequest(request, response);
		} finally {
			postProcessRequest(request, response);
		}
	}

	protected void preProcessRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

	}

	protected void postProcessRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		Exception e = null;
		try {
			if(DbRegistry.isConnected()) // test avoids an NPE bug in closeDbConnectionIfNeeded @ line 150.
				DbRegistry.closeDbConnectionIfNeeded();
		} catch (Exception e1) {
			e = e1;
		}
		ThreadLocalTracker.purgeThreadLocal();
		if (e != null)
			throw new ServletException("postProcessRequest database close", e);
	}

	private String getParameterOrAttribute(HttpServletRequest request, String key) {
		String value = request. getParameter(key);
		if (value == null) {
			value = (String) request.getAttribute(key);
		}
		return value;
	}
}
